using System;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace sgsBase
{
	/// <summary>
	/// Summary description for Email.
	/// </summary>
	public class Email
	{
		public static string TestAddress = "";
		public static string BCC = "";
		private static bool _error_message = false;
		public static string ErrorString = "";
		private static DateTime _lastSentTime;

		public Email()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public static void Send(string to, string subject, string body, MailPriority mpri, string attach)
		{
			Send(to, BaseStaticData.EmailUser, subject, body, mpri, attach);
		}

		public static void Send(string to, string subject, string body, MailPriority mpri)
		{
			Send(to, subject, body, mpri, "");
		}

		public static void Send(string to, string subject, string body)
		{
			Send(to, subject, body, MailPriority.Normal, "");
		}

		public static void Send(string to, MailAddress ma, string subject, string body, MailPriority mpri, string attach)
		{
			Attachment att = null;

			to = to.Trim(',');
			try
			{
				ErrorString = "";
				MailMessage objEmail = new MailMessage();

				if (TestAddress != "")
				{
					objEmail.To.Add(TestAddress);
					body += "<p>Would have sent to : " + to + "</p>";
				}
				else
					AddEmailAddresses(objEmail, to);
				//objEmail.To.Add(to);

				if (BCC != "")
					objEmail.Bcc.Add(BCC);

				objEmail.From = ma;
				objEmail.Subject = subject;
				objEmail.Body = body;
				objEmail.Priority = mpri;
				objEmail.IsBodyHtml = true;

				if (attach != "")
				{
					att = new Attachment(attach);
					objEmail.Attachments.Add(att);
				}

				// Load server parameters
				SmtpClient sc = new SmtpClient(BaseStaticData.EmailServerIP);

				sc.Credentials = new System.Net.NetworkCredential(BaseStaticData.EmailUser, BaseStaticData.EmailPass);

				sc.Port = BaseStaticData.EmailPort;

				Thread sendThread = new Thread(new ParameterizedThreadStart(_threadedSend));
				sendThread.Start(objEmail);
				//sc.Send(objEmail);
			}
			catch (Exception ex)
			{
				ErrorString = ex.ToString();
				//if (!_error_message)
				//	Email.SendError("Email Error", to, ex);
			}
			if (att != null)
				att.Dispose();
		}

		public static void Send(string to, string from, string subject, string body, MailPriority mpri, string Attach)
		{
			MailAddress ma = new MailAddress(from, from);
			Send(to, ma, subject, body, mpri, Attach);
		}

		public static void Send(string to, string from, string subject, string body, MailPriority mpri)
		{
			MailAddress ma = new MailAddress(from, from);
			Send(to, ma, subject, body, mpri, "");
		}

		public static void Send(string to, string from, string subject, string body)
		{
			Send(to, from, subject, body, MailPriority.Normal);
		}

		private static void _threadedSend(object objEmail)
		{
			try
			{
				SmtpClient sc = new SmtpClient(BaseStaticData.EmailServerIP);

				sc.Credentials = new System.Net.NetworkCredential(BaseStaticData.EmailUser, BaseStaticData.EmailPass);
				sc.Port = BaseStaticData.EmailPort;

				sc.Send((MailMessage) objEmail);
			}
			catch //(Exception ex)
			{
				//Email.SendError("Email Error", ((MailMessage)objEmail).To.ToString(), ex);
			}
		}

		/// <summary>
		/// Separates out multiple email addresses and adds them to the message. 
		/// </summary>
		/// <param name="mm"></param>
		/// <param name="tos"></param>
		/// make sure the same ID is not added twice. 
		private static void AddEmailAddresses(MailMessage mm, string tos)
		{
			try
			{
				tos = tos.Trim();
				if (tos.IndexOf(" ") > 0 || tos.IndexOf(",") > 0 || tos.IndexOf(";") > 0)
				{
					char[] seps = {' ', ',', ';'};
					List<string> tolist = new List<string>();
					List<string> added = new List<string>();
					string found;
					string to;
					tolist.AddRange(tos.Split(seps));

					foreach (string eto in tolist)
					{
						to = eto.Trim().ToLower();
						if (to != "")
						{
							found = added.Find(delegate(string lad)
								                   {
									                   return (lad == to);
								                   });

							if (found == null && to.IndexOf("@") > 0)
							{
								mm.To.Add(to);
								added.Add(to);
							}
						}
					}

				}
				else
					mm.To.Add(tos);
			}
			catch (Exception ex)
			{
				if (tos != "" && _error_message == false)
					Email.SendError("Bad Email Address", tos, ex);
			}
		}

		public static void SendError(string subject, string body, Exception ex, string addl_stack)
		{
			if (DateTime.Now.Hour >= 23 || DateTime.Now.Hour < 6)
			{
				var minutes = (DateTime.Now.TimeOfDay - _lastSentTime.TimeOfDay).TotalMinutes;
				if (minutes < 10)
				{
					Thread.Sleep(300000);
					return;
				}
		    }

			_lastSentTime = DateTime.Now;
			if (addl_stack == "")
				addl_stack = Environment.StackTrace;

			var stackinfo = body;
			if (_error_message)
			{
				StreamWriter sw = new StreamWriter(ApplicationHelper.PhysicalPath + "error.log", true);
				sw.WriteLine(DateTime.Now.ToString() + " : ERROR : " + ex.Message);
				sw.WriteLine(subject);
				sw.WriteLine(body);
				sw.Close();
				return;
			}
			_error_message = true;
			if (ex != null)
			{
				stackinfo += "<br><table style='border: 1px solid gray'><tr><td><b>Message:</b><td>" + ex.Message + "</td></tr>";
				stackinfo += "<tr><td><b>Computer:</b><td>" + System.Environment.MachineName + "</td></tr>";
				stackinfo += "<tr><td><b>Source:</b><td>" + ex.Source + "</td></tr>";
				stackinfo += "<tr><td valign='top'><b>StackTrace:</b><td>" + ex.StackTrace.Replace("\n", "<br>") + "</td></tr>";
				if (addl_stack != "")
				{
					stackinfo += "<tr><td valign='top' style='border-top: solid 1px black;'><b>Addl StackTrace:</b><td>" +
					             addl_stack.Replace("\n", "<br>") + "</td></tr>";
				}
				stackinfo += "</table>";
			}

			Send(BaseStaticData.NotifyDeveloper, BaseStaticData.EmailUser,
			     BaseStaticData.BaseApp + " " + BaseStaticData.RunningSystem + ": " + subject, stackinfo, MailPriority.High);
			_error_message = false;
	    }

		public static void SendError(string subject, string body, Exception ex)
		{
			SendError(subject, body, ex, "");
		}

		public static void SendError(string subject, string body)
		{
			SendError(subject, body, null, "");
		}

		public static void SendError(string subject, Exception ex)
		{
			SendError(subject, "", ex);
		}

		public static void SendError(Exception ex)
		{
			SendError("General thcStore Error", "", ex, "");
		}

		public static void SendTrace(string body)
		{
			SendError("Trace", body, null);
		}

		public static string BuildWithTemplate(string content, string template="")
		{
			string file = "";
			if (template == "")
				file = ApplicationHelper.DefaultMailTemplate;
			else
				file = ApplicationHelper.PhysicalPath + template;

			FileStream fs = File.OpenRead(file);
			StreamReader sr = new StreamReader(fs);
			string emailbody = sr.ReadToEnd();
			sr.Close();
			fs.Close();

			emailbody = emailbody.Replace("%siteTitle%", ApplicationHelper.SiteTitle);
			emailbody = emailbody.Replace("%content%", content);

			return emailbody;
		}
	}
}
